package com.darwin.darwinMVC.mvc
{
	
	import com.darwin.darwinMVC.commands.SourceCommand;
	import com.darwin.darwinMVC.core.ContextPlace;
	import com.darwin.darwinMVC.core.Resolver;
	
	import flash.utils.Dictionary;
	import com.darwin.darwinMVC.core.Context;

	/**
	 * 数据源。项目中的所有数据的来源，包话配置文件和后台接口
	 * @author lipi
	 */
	public class DataSource
	{
		public function DataSource()
		{
			_dataMap = new Dictionary();
			_interimMap = new Dictionary();
			_context = ContextPlace.getContext();
			_resolverMap = new Dictionary();
		}
		
		//数据字典
		private var _dataMap:Dictionary;
		
		private var _context:Context;
		
		//临时数据字典
		private var _interimMap:Dictionary;
		
		//解析器字典
		private var _resolverMap:Dictionary;
		
		
		/**
		 * 写入一个数据项
		 * @param dataName 数据项的名字
		 * @param dataValue 数据
		 */
		public function setData(dataName:String,dataValue:*):void
		{
			if(!_lock)
			{
				_dataMap[dataName] = resolverData(dataName,dataValue);
				var $cmd:SourceCommand = new SourceCommand(dataName,this);
				$cmd.data = dataValue;
				_context.dispatch($cmd);
			}else{
				_interimMap[dataName] = dataValue;
			}
		}
		
		/**
		 * 取得一个数据
		 * @param dataName 数据项名
		 * @return 返回的数据
		 */
		public function getData(dataName:String):Object
		{
			return _dataMap[dataName];
		}
		
		
		private var _lock:Boolean = false;
		/**
		 * 锁定命令的发布。被锁定后setData被调用后将不发布命令，主要使用在需要同一时间写入多条数据的时候。（请即时解锁）
		 */
		public function lockCommandNotify():void
		{
			_lock = true;
		}
		
		/**
		 * 对命令发布进行解锁
		 */
		public function unlockCommandNotify():void
		{
			_lock = false;
			for each(var name:String in _interimMap)
			{
				_dataMap[name] = resolverData(name,_interimMap[name]);
				var $cmd:SourceCommand = new SourceCommand(name,this);
				$cmd.data = _dataMap[name];
				_context.dispatch($cmd);
				delete _interimMap[name];
			}
		}
		
		
		/**
		 * 解析一个数据
		 * @param name
		 * @param data
		 * @return 
		 */
		private function resolverData(name:String,data:Object):Object
		{
			var $data:Object;
			if(_resolverMap[name] == null)
			{
				$data = data;
			}else{
				var $resolver:Resolver = _resolverMap[name] as Resolver;
				$data = $resolver.execute(data);
			}
			return $data;
		}
		
		/**
		 * 增加一个数据解析程序
		 * @param dataName 源数据名
		 * @param resolver 解析器
		 */
		public function addResolver(dataName:String,resolver:Resolver):void
		{
			if(_dataMap[dataName] != null)
			{
				_dataMap[dataName] = resolver.execute(_dataMap[dataName]);
			}
			_resolverMap[dataName] = resolver;
		}
		
	}
}